package ai.platon.pulsar.protocol.browser.driver.selenium

import ai.platon.pulsar.browser.common.BrowserSettings
import ai.platon.pulsar.browser.driver.chrome.ChromeLauncherApi
import ai.platon.pulsar.browser.driver.chrome.RemoteChrome
import ai.platon.pulsar.browser.driver.chrome.common.ChromeOptions
import ai.platon.pulsar.browser.driver.chrome.common.LauncherOptions
import ai.platon.pulsar.browser.driver.chrome.impl.ChromeImpl
import ai.platon.pulsar.common.config.ImmutableConfig
import com.alibaba.fastjson2.JSON
import com.alibaba.fastjson2.JSONObject
import com.mulei.okhttp.OKHttpUtils
import okhttp3.OkHttpClient
import org.apache.commons.lang3.StringUtils
import org.slf4j.LoggerFactory
import java.net.URI
import java.net.URISyntaxException
import kotlin.collections.set

class RemoteChromeLauncher(options: LauncherOptions) : ChromeLauncherApi(options) {
    private var browserId: String = ""
    private val okHttpClient = OkHttpClient()
    private val logger = LoggerFactory.getLogger(RemoteChromeLauncher::class.java)

    override fun close() {
      close(this.browserId)
    }
    fun  close(browserId:String){
        logger.info("try close browser {}", browserId)
        if (StringUtils.isBlank(this.browserId)) {
            logger.error("this browser is empty")
            return
        }
        val settings: BrowserSettings = options.browserSettings
        val webdriverUri = settings.webdriverUri
        val uri = if (StringUtils.isBlank(settings.webdriverToken)) String.format(
            "http://%s/kill",
            webdriverUri,
        ) else String.format("http://%s/kill?%s", webdriverUri, settings.webdriverToken)
        var json = JSONObject();
        json.put("chrome.browser.id", browserId);
        val request = OKHttpUtils.request(this.okHttpClient, "POST", uri, json.toJSONString())
        logger.error("try to request uri {} result {}", uri, request)
    }

    override fun destroyForcibly() {
        this.close()
    }

    override fun launch(chromeOptions: ChromeOptions): RemoteChrome {
        val settings = options.browserSettings
        val webdriverUri = settings.webdriverUri
        val uri = if (StringUtils.isBlank(settings.webdriverToken)) String.format(
            "http://%s/launch",
            webdriverUri
        ) else String.format("http://%s/launch?%s", webdriverUri, settings.webdriverToken)
        val jsonObject = JSONObject()
        jsonObject["options"] = JSONObject.toJSONString(chromeOptions)
        val post = OKHttpUtils.request(this.okHttpClient, "POST", uri, jsonObject.toJSONString())
        logger.error("try to request uri {} result {}", uri, jsonObject)
        if (StringUtils.isBlank(post)) {
            throw IllegalStateException("can not raise a chrome");
        }
        val res = JSONObject.parseObject(post)
        this.browserId = res.getString("chrome.browser.id")
        return ChromeImpl(baseUri = webdriverUri, token = "", id = browserId)
    }

    override fun launch(headless: Boolean): RemoteChrome {
        val options = ChromeOptions()
        options.headless = headless
        return launch(options)
    }

    override fun launch(): RemoteChrome {
        return launch(true)
    }

    fun port(uri: String?): Int? {
        if (StringUtils.isBlank(uri)) {
            return null
        }
        try {
            return URI(uri).port
        } catch (e: URISyntaxException) {
            throw RuntimeException(e)
        }
    }

    fun host(uri: String?): String? {
        if (StringUtils.isBlank(uri)) {
            return null
        }
        try {
            return URI(uri).host
        } catch (e: URISyntaxException) {
            throw RuntimeException(e)
        }
    }

    companion object {

        @JvmStatic
        fun main(args: Array<String>) {
            //        String put = request(new OkHttpClient(),"put", "http://localhost:3600/json/new?https://www.baidu.com", "");
//        System.err.println(put);
//        if (true){
//            return;
//        }

            BrowserSettings.withRemoteDriverUri("localhost:8081")
            val settings = BrowserSettings(ImmutableConfig())
            var options = LauncherOptions()
            options.browserSettings = settings
            val launcher = RemoteChromeLauncher(options)
            val launch = launcher.launch(true)
            println(launch.toString())
            val tab = launch.createTab("https://www.baidu.com")
            println(tab.url)
            launcher.close()
        }
    }
}
